package com.annual.web.controller.wechat;

import cn.hutool.core.util.ObjectUtil;
import com.annual.common.config.WxPayConfig;
import com.annual.common.constant.Constants;
import com.annual.system.service.IOrderService;
import com.annual.system.wechat.PayUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wechat.pay.java.core.exception.ValidationException;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RSAPublicKeyNotificationConfig;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

@Api(tags = "微信回调控制器")
@RestController
@RequestMapping("/wechat/eb/callback")
@Slf4j
public class WechatCallbackController {
    @Autowired
    private IOrderService orderService;

    @ApiOperation(value = "微信支付回调", notes = "ywb")
    @PostMapping(value = "payment")
    public Map<String, String> payment(HttpServletRequest request) {
        log.info("微信支付回调----->进入回调");
        Map<String, String> map = new HashMap<>(2);
        String signature     = request.getHeader("Wechatpay-Signature");//应答的微信支付签名
        String serial        = request.getHeader("Wechatpay-Serial");//微信支付平台证书的序列号，验签必须使用序列号对应的微信支付平台证书
        String nonce         = request.getHeader("Wechatpay-Nonce");//签名中的随机数
        String timestamp     = request.getHeader("Wechatpay-Timestamp");//签名中的时间戳
        String signatureType = request.getHeader("Wechatpay-Signature-Type");//签名类型
        String requestBody = "";
        try {
            //读取请求体的信息
            ServletInputStream inputStream = request.getInputStream();
            StringBuffer stringBuffer = new StringBuffer();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String s;
            //读取回调请求体
            while ((s = bufferedReader.readLine()) != null) {
                stringBuffer.append(s);
            }
            requestBody = stringBuffer.toString();
        }catch (Exception e){
            e.printStackTrace();
            map.put("code","FAIL");
            map.put("message","失败");
            return map;
        }
        log.info("微信支付回调-Signature:{}",signature);
        log.info("微信支付回调-Serial:{}",serial);
        log.info("微信支付回调-Nonce:{}",nonce);
        log.info("微信支付回调-Timestamp:{}",timestamp);
        log.info("微信支付回调-Signature-Type:{}",signatureType);
        log.info("微信支付回调-requestBody:{}",requestBody);
        // 构造 equestParam
        RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(serial)
                .nonce(nonce)
                .signature(signature)
                .timestamp(timestamp)
                .signType(signatureType)
                .body(requestBody)
                .build();
        // 初始化 NotificationParser
        NotificationParser parser = new NotificationParser(PayUtil.getNotificationConfig());
        try {
            // 以支付通知回调为例，验签、解密并转换成 Transaction
            Transaction transaction = parser.parse(requestParam, Transaction.class);
            String outTradeNo = transaction.getOutTradeNo();
            if(transaction.getTradeState().toString().equals("SUCCESS")){
                orderService.updateOrderstatus(outTradeNo,2);
            }
            map.put("code","SUCCESS");
            map.put("message","成功");
            log.info("支付通知回调：{}",transaction.toString());
        } catch (ValidationException e) {
            e.printStackTrace();
            map.put("code","FAIL");
            map.put("message","失败");
            return map;
        }
        map.put("code","FAIL");
        map.put("message","失败");
        return map;
    }


}
